//
//  CEILinePlot.m
//  Balance
//
//  Created by Calvin Kuo on 12-05-10.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

/*
 Status: changed
 Last Merge Date: 06-08-2012
 Last Change Date: 
 Changes:
 1. prior year animation
 2. ruller cannot be scrolled to far right
 
 */


#import "CEILinePlot.h"
#import "CEIData.h"

@implementation CEILinePlot

#define oneDayInterval 86400 //60*60*24
#define initNumberOfDaysDisplayed 183
#define kCurrentPlot @"SelectedCollectorPlot" 
#define kPriorPlot @"ProiorYearPlot" 
#define kAllCollectorsPlot @"AllCollectorsPlot"
#define kRulerPlot @"RulerPlot"
#define numberOfMarkerPlotSymbols 2
#define kRepeat 20 //repeat count, used for animation
#define kFrameRate 20  // frames per second, used for animation

- (id)init
{
    self = [super init];
    if (self) { 
        dailyCEI = nil;  
    }

    return self;
}

- (id) initWithOneCollectorData:(NSMutableDictionary *) ceiData allCollectorsData:(NSMutableDictionary *) allData{
    self = [self init];
    if (self) {
        dailyCEI = ceiData;
        dailyKeys = [dailyCEI allKeys];
        totalNoOfDataPoints = [dailyCEI count];
                
        NSDate * today = [[NSDate alloc]init];
        initStartDate = [today dateByAddingTimeInterval:(oneDayInterval *initNumberOfDaysDisplayed * -1)];
        NSDateFormatter *ceiFormatter = [[NSDateFormatter alloc] init];
        [ceiFormatter setDateFormat:@"yyyyMMdd"];
        initStartDateString = [ceiFormatter stringFromDate:initStartDate];
        
        //NSLog(@"cei initStartDateString = %@",initStartDateString);
               
        dailyKeys = [dailyKeys sortedArrayUsingSelector:@selector(compare:)];
        NSInteger initStartIndex = [dailyKeys indexOfObject:initStartDateString];
        
        dailyKeysInRange = [[NSMutableArray alloc] init];
        for (int i=initStartIndex; i <totalNoOfDataPoints; i++){
            [dailyKeysInRange addObject:[dailyKeys objectAtIndex:i]];
        }
        
        NoOfDataPointsInRange = [dailyKeysInRange count];
        //NSLog(@"cei NoOfDataPointsInRange = %i",NoOfDataPointsInRange);       
        //set up data for priorPlot
       /* dailyKeysInPriorRange = [[NSMutableArray alloc] init];
        for (int i=(initStartIndex-initNumberOfDaysDisplayed); i <totalNoOfDataPoints; i++){
            [dailyKeysInPriorRange addObject:[dailyKeys objectAtIndex:i]];
        }*/

        //set up data for allCollectorsPlot
        allCollectorsCEI = allData;
        allCollectorsKeys = [allCollectorsCEI allKeys];
        allCollectorsKeys = [allCollectorsKeys sortedArrayUsingSelector:@selector(compare:)];
        allCollectorsKeysInRange = [[NSMutableArray alloc] init];
        for (int i=initStartIndex; i <totalNoOfDataPoints; i++){
            [allCollectorsKeysInRange addObject:[allCollectorsKeys objectAtIndex:i]];
        }
            

        //initial position of ruler; 
        rulerIndex = NoOfDataPointsInRange -1; //today
        rulerDateString = [dailyKeysInRange objectAtIndex:rulerIndex];    
            
        allCollectorsPlotAdded = NO;
        priorPlotAdded = NO;    
        rangeChanged = NO;
        rulerEnabled = NO;
                     
    }
    
    
    
    
    return self;

}

- (void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme{
    
    
    CGRect bounds = layerHostingView.bounds;
    
    graph = [[CPTXYGraph alloc] initWithFrame:bounds];
    layerHostingView.hostedGraph = graph;
    layerHostingView.backgroundColor = [UIColor colorWithWhite:0.7f alpha:1.0f]; 
    
    CPTGradient *plotAreaGradient = [CPTGradient gradientWithBeginningColor:[CPTColor colorWithGenericGray:0.9f]endingColor:[CPTColor colorWithGenericGray:0.7f]];
    plotAreaGradient.angle = -90.0;
    graph.plotAreaFrame.plotArea.fill = [CPTFill fillWithGradient:plotAreaGradient]; 
    
    [graph applyTheme:theme];
   
    graph.plotAreaFrame.masksToBorder = NO;
    
    CPTMutableTextStyle *blackTextStyle = [[CPTMutableTextStyle alloc] init];
    //blackTextStyle.color = [CPTColor blackColor];
    blackTextStyle.color = [CPTColor colorWithComponentRed:0.2 green:0.2 blue:0.2 alpha:0.82]; //RGB:R51-G51-B51
	blackTextStyle.fontSize = 20.0;
    graph.titleTextStyle = blackTextStyle;
    graph.titleDisplacement = CGPointMake(0.0, 90.0); 
    graph.title = @"Collection Effectiveness Index";
    
    
    
    
    // change the chart layer orders so the axis line is on top of the bar in the chart.
    NSArray *chartLayers = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:CPTGraphLayerTypePlots],
                            [NSNumber numberWithInt:CPTGraphLayerTypeMajorGridLines], 
                            [NSNumber numberWithInt:CPTGraphLayerTypeMinorGridLines],  
                            [NSNumber numberWithInt:CPTGraphLayerTypeAxisLines], 
                            [NSNumber numberWithInt:CPTGraphLayerTypeAxisLabels], 
                            [NSNumber numberWithInt:CPTGraphLayerTypeAxisTitles], 
                            nil];
    graph.topDownLayerOrder = chartLayers;    
    
    
    // Add plot space for horizontal bar charts
    graph.paddingLeft = 90.0;
	graph.paddingTop = 120.0;//50.0
	graph.paddingRight = 50.0;
	graph.paddingBottom = 50.0;//60.0
    
    // Setup plot space
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    plotSpace.allowsUserInteraction = YES;
    plotSpace.delegate = self;
    
    //display last 6 months starting today
    plotSpace.xRange=[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(oneDayInterval*0) 
                                                  length:CPTDecimalFromFloat(oneDayInterval*initNumberOfDaysDisplayed)];
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(100)];
    
    //set globalXrange same as xRange preventing from horizontal scrolling
    /*plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f)
     length:CPTDecimalFromFloat(oneDayInterval*maxNumberOfBalancesDisplayed)];*/
    
    // Setup grid line style
    CPTMutableLineStyle *majorXGridLineStyle = [CPTMutableLineStyle lineStyle];
    majorXGridLineStyle.lineWidth = 1.0f;
    majorXGridLineStyle.lineColor = [[CPTColor grayColor] colorWithAlphaComponent:0.25f];
    
    // Setup x-Axis.
	CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x = axisSet.xAxis;
    x.majorGridLineStyle = majorXGridLineStyle;
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    
    //setup x axis label based on weeks; one label per 7 days
    
    x.majorIntervalLength = CPTDecimalFromFloat(oneDayInterval*30.0);
    x.minorTicksPerInterval = 0;
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateStyle = kCFDateFormatterShortStyle; // format is mm/dd/yy
    CPTTimeFormatter *timeFormatter =[[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
    
    timeFormatter.referenceDate = initStartDate;
    x.labelFormatter = timeFormatter;
    
    
    // Setup y-Axis.
    CPTMutableLineStyle *majorYGridLineStyle = [CPTMutableLineStyle lineStyle];
    majorYGridLineStyle.lineWidth = 1.0f;
    majorYGridLineStyle.dashPattern =  [NSArray arrayWithObjects:[NSNumber numberWithFloat:5.0f], [NSNumber numberWithFloat:5.0f], nil];
    majorYGridLineStyle.lineColor = [[CPTColor lightGrayColor] colorWithAlphaComponent:0.25];
    
    
    CPTXYAxis *y = axisSet.yAxis;
    
    y.majorGridLineStyle = majorYGridLineStyle;
    y.majorIntervalLength = CPTDecimalFromString(@"20");
    y.minorTicksPerInterval = 1;
    y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    y.title = @"Rolling CEI (%)";
    NSArray *yExlusionRanges = [NSArray arrayWithObjects:
                                [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(0.0)],
                                nil];
    y.labelExclusionRanges = yExlusionRanges;
    NSNumberFormatter *percentFormatter = [[NSNumberFormatter alloc] init];
    //[percentFormatter setNumberStyle:NSNumberFormatterPercentStyle];
    [percentFormatter setNumberStyle:NSNumberFormatterNoStyle];
    y.labelFormatter = percentFormatter;
      
    //y-axis stays in fixed position
    axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0];
    
    
    // Create 1st plot area in Blue for balance
    currentPlot = [[CPTScatterPlot alloc] init];
    currentPlot.identifier = kCurrentPlot;
    
    CPTMutableLineStyle *currentLineStyle = [currentPlot.dataLineStyle mutableCopy];
	currentLineStyle.lineWidth = 2.f;
    currentLineStyle.lineColor = [CPTColor colorWithComponentRed:0.051 green:0.388 blue:0.894 alpha:1.0]; //RGB: 13-99-228  (blue)
    
    currentPlot.dataLineStyle = currentLineStyle;
    currentPlot.dataSource = self;  
        
    CPTMutableShadow *blackShadow = [CPTMutableShadow shadow];
    blackShadow.shadowOffset	 = CGSizeMake(0.0, -7.0);
    blackShadow.shadowBlurRadius = 6.0;
    blackShadow.shadowColor		 = [CPTColor blackColor];
    currentPlot.shadow= blackShadow;    
    
    [graph addPlot:currentPlot];
    
    
    // Create the baseline plot
	priorPlot = [[CPTScatterPlot alloc] init];
    priorPlot.identifier = kPriorPlot;
    
	CPTMutableLineStyle *priorLineStyle = [currentPlot.dataLineStyle mutableCopy];
	priorLineStyle.lineWidth = 2.f;
    priorLineStyle.lineColor = [CPTColor colorWithComponentRed:0.078 green:0.529 blue:0.0 alpha:1.0]; //RGB: 20-135-0  (green)
    priorPlot.dataLineStyle = priorLineStyle;
    priorPlot.dataSource = self;  
    priorPlot.shadow = blackShadow; 
    //[graph addPlot:priorPlot];
    
    
    // Create the all collectors plot
	allCollectorsPlot = [[CPTScatterPlot alloc] init];
    allCollectorsPlot.identifier = kAllCollectorsPlot;
    
	CPTMutableLineStyle *allLineStyle = [currentPlot.dataLineStyle mutableCopy];
	allLineStyle.lineWidth = 2.f;
    allLineStyle.lineColor = [CPTColor colorWithComponentRed:0.882 green:0.18 blue:0.137 alpha:1.0];   //RGB: 225-46-35  (orange)
    allCollectorsPlot.dataLineStyle = allLineStyle;
    allCollectorsPlot.dataSource = self;  
    allCollectorsPlot.shadow = blackShadow; 
    //[graph addPlot:allCollectorsPlot];
    
    //create the ruler plot
    rulerPlot =  [[CPTScatterPlot alloc] initWithFrame:CGRectNull];
    rulerPlot.identifier = kRulerPlot;
    rulerPlot.dataSource = self;
    //[self applyRulerPlotColor];
    //[self displayRulerAnnotation];  
    //[graph addPlot:rulerPlot];
    
    
    //add legends
    currentPlot.title = @"CEI";
    priorPlot.title = @"Prior Year";
    allCollectorsPlot.title = @"CEI For All";
    
    CPTLegend *lineLegend = [CPTLegend legendWithPlots:[NSArray arrayWithObjects:currentPlot, allCollectorsPlot, priorPlot, nil]]; 
    lineLegend.numberOfColumns = 3;
    graph.legend= lineLegend;
    graph.legend.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
    graph.legend.cornerRadius = 5.0;
    graph.legend.swatchSize = CGSizeMake(10.0, 10.0);
    graph.legendAnchor = CPTRectAnchorTop;  //CPTRectAnchorRight
    graph.legendDisplacement = CGPointMake(0.0, -80.0);  //position of the legend
    
    CPTMutableTextStyle *legendTextStyle = [[CPTMutableTextStyle alloc] init];
	legendTextStyle.color = [CPTColor darkGrayColor];
	legendTextStyle.fontSize = 11.0;
    legendTextStyle.fontName = @"Helvetica-Bold";
    graph.legend.textStyle = legendTextStyle;

    

      
}


// Assign different color to the touchable line symbol.
- (void)applyRulerPlotColor{
    
    CPTMutableLineStyle *rulerLineStyle = [CPTMutableLineStyle lineStyle];
    rulerLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:4.0f], nil];
    rulerLineStyle.lineColor = [CPTColor cyanColor];
    //rulerLineStyle.lineColor = [CPTColor colorWithComponentRed:0.129 green:0.545 blue:0.894 alpha:1.0]; //RGB: 33-139-228  (blue) 
    rulerLineStyle.lineWidth = 2.0f;
    rulerPlot.dataLineStyle = rulerLineStyle;
    
}

// Highlight the touch plot when the user holding tap on the line symbol.
- (void)highlightRulerPlotColor{
    
    CPTMutableLineStyle *selectedRulerLineStyle = [CPTMutableLineStyle lineStyle];
    selectedRulerLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:4.0f], nil];
    selectedRulerLineStyle.lineColor = [CPTColor yellowColor];
    selectedRulerLineStyle.lineWidth = 2.0f;
    rulerPlot.dataLineStyle = selectedRulerLineStyle;
}

-(void)removeRulerAnnotation{
    if ( symbolTextAnnotation ) {
        [graph.plotAreaFrame.plotArea removeAnnotation:symbolTextAnnotation];
        symbolTextAnnotation = nil;
    };
}

-(void)displayRulerAnnotation
{
    
    if ( symbolTextAnnotation ) {
        [graph.plotAreaFrame.plotArea removeAnnotation:symbolTextAnnotation];
        symbolTextAnnotation = nil;
    };
    
    
    
    // Setup a style for the annotation
    CPTMutableTextStyle *hitAnnotationTextStyle = [CPTMutableTextStyle textStyle];
    hitAnnotationTextStyle.color	= [CPTColor cyanColor];
    //hitAnnotationTextStyle.color = [CPTColor colorWithComponentRed:0.129 green:0.545 blue:0.894 alpha:1.0]; //RGB: 33-139-228  (blue) 
    hitAnnotationTextStyle.fontSize = 13.0f;
    hitAnnotationTextStyle.fontName = @"Helvetica-Bold";
    
    NSString *refDateString = [dailyKeysInRange objectAtIndex:0];
    CEIData *refData = [dailyCEI objectForKey: refDateString];
    CEIData *rulerData = [dailyCEI objectForKey: rulerDateString];
    
        
    NSArray *anchorPoint = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat: (refData.timeIntervalSinceToday - rulerData.timeIntervalSinceToday)],
                            [NSNumber numberWithInt:110],nil];
    
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"MM/dd/yyyy"];
    //[dateFormat setDateStyle:NSDateFormatterMediumStyle];
    NSString *asOfDateString = [dateFormat stringFromDate:rulerData.ceiDate];
    NSString *formattedPercent = [NSString stringWithFormat:@"%.02f", [rulerData.ceiPercent floatValue]];

    NSString *rulerString = [NSString stringWithFormat:@" %@%% - %@ \n" 
                            , formattedPercent,asOfDateString];
    
    // Now add the annotation to the plot area
    CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:rulerString style:hitAnnotationTextStyle];
    symbolTextAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:graph.defaultPlotSpace anchorPlotPoint:anchorPoint];
    
    //UIImage *popoverImage = [UIImage imageNamed:@"popover.png"];
    //textLayer.backgroundColor = [UIColor colorWithPatternImage:popoverImage].CGColor;
    textLayer.backgroundColor = [UIColor blackColor].CGColor;
    textLayer.frame = CGRectMake(0,0, 130, 20); 

    symbolTextAnnotation.contentLayer = textLayer;
    symbolTextAnnotation.displacement = CGPointMake(0.0f, -35.0f);
    [graph.plotAreaFrame.plotArea addAnnotation:symbolTextAnnotation];
    
       
}


- (void)removePlot:(NSString *)plotIdentifier{
    
    if ([plotIdentifier isEqualToString:kPriorPlot]){ 
        [graph removePlot:priorPlot];
        priorPlotAdded = NO;
    }
    else if ([plotIdentifier isEqualToString:kAllCollectorsPlot]){ 
        [graph removePlot:allCollectorsPlot];
        allCollectorsPlotAdded = NO;
    }
          
}

- (void)addPlot:(NSString *)plotIdentifier{
    
    if ([plotIdentifier isEqualToString:kPriorPlot]){ 
        [graph addPlot:priorPlot];
        priorPlotAdded = YES;
    }
    else if ([plotIdentifier isEqualToString:kAllCollectorsPlot]){ 
        [graph addPlot:allCollectorsPlot];
        allCollectorsPlotAdded = YES;

    }
    
}

# pragma CEISliderPlotDelegate
//change the date range responding to the range plot
-(void)respondToRangeChangeFromDate:(NSString *)newFromDateString toDate:(NSString *)newToDateString
{
       
    NSInteger startIndex = [dailyKeys indexOfObject:newFromDateString];
    NSInteger endIndex = [dailyKeys indexOfObject:newToDateString];
    //NSLog(@"newFromDateString=%@,startIndex=%i,newToDateString=%@,endIndex=%i",newFromDateString,startIndex,newToDateString,endIndex);
      
    int NoOfDaysInRange = endIndex - startIndex +1;;
 
    if (NoOfDaysInRange != NoOfDataPointsInRange)
        rangeChanged = YES;
    
    int gap = 1;
    if (NoOfDaysInRange > initNumberOfDaysDisplayed*1.5) {
        gap = (NoOfDaysInRange/initNumberOfDaysDisplayed)+1;
    };
        
   
    //for animation. Copy dailyKeysInRange as it will be changed soon.
    animationStartDailyKeys = [NSMutableArray arrayWithCapacity:2000]; 
    for (int s=0;s<NoOfDataPointsInRange;s++){
        [animationStartDailyKeys addObject:[dailyKeysInRange objectAtIndex:s]];
    };
    
    
    //refresh the current plot for the new range         
    NSMutableArray *displayDailyKeys  = [NSMutableArray arrayWithCapacity:5000];
    
    for (int idx= startIndex; idx < endIndex+1; idx++){
        [displayDailyKeys addObject:[dailyKeys objectAtIndex:idx]];
    };
    
    /*if ((gap > 1) && (startIndex%gap != 0))
        [displayDailyKeys addObject:[dailyKeys objectAtIndex:startIndex]];
    
    for (int idx= startIndex; idx < endIndex+1; idx++){
        if (idx%gap ==0){
            [displayDailyKeys addObject:[dailyKeys objectAtIndex:idx]];
        };
    };
    
    if ((gap > 1) && (endIndex%gap !=0))
        [displayDailyKeys addObject:[dailyKeys objectAtIndex:endIndex]];
     */

     if (rulerEnabled){ 
        rulerIndex = (rulerIndex * [displayDailyKeys count]) / NoOfDataPointsInRange;
    }
      
    dailyKeysInRange = displayDailyKeys;
    NoOfDataPointsInRange = [dailyKeysInRange count];
    //NSLog(@"NoOfDaysInRange=%i, NoOfDataPointsInRange=%i",NoOfDaysInRange,NoOfDataPointsInRange);
    
    //set up animation data
    [self prepareAnimationData];
    
    if (rulerEnabled){
        rulerDateString = [dailyKeysInRange objectAtIndex:rulerIndex];
        [self displayRulerAnnotation];
    }
        

    
    //-----------------------------------------------------
    //refresh the all collectors plot for the new range         
    NSMutableArray *displayAllCollectorsKeysInRange  = [NSMutableArray arrayWithCapacity:5000];
    for (int idx= startIndex; idx < endIndex+1; idx++){
        [displayAllCollectorsKeysInRange addObject:[dailyKeys objectAtIndex:idx]];
    };
    
    /*if ((gap > 1) || startIndex%gap !=0)
        [displayAllCollectorsKeysInRange addObject:[dailyKeys objectAtIndex:startIndex]];
    
    for (int idx= startIndex; idx < endIndex+1; idx++){
        if (idx%gap ==0){
            [displayAllCollectorsKeysInRange addObject:[dailyKeys objectAtIndex:idx]];
        };
    };
    
    if ((gap > 1) || endIndex%gap !=0)
        [displayAllCollectorsKeysInRange addObject:[dailyKeys objectAtIndex:endIndex]];
    */
    allCollectorsKeysInRange = displayAllCollectorsKeysInRange;
       
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(oneDayInterval*0) 
                                                    length:CPTDecimalFromFloat(oneDayInterval* (NoOfDaysInRange-1))];
    
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x = axisSet.xAxis;
    
    x.majorIntervalLength = CPTDecimalFromFloat(oneDayInterval*30.0 * gap);
    
    NSDateFormatter *fromDateFormatter = [[NSDateFormatter alloc] init];
    [fromDateFormatter setDateFormat:@"yyyyMMdd"];
    NSDate *newFromDate = [fromDateFormatter dateFromString:newFromDateString]; 
    NSDate *refDate = newFromDate;   
    
    NSDateFormatter *refDateFormatter = [[NSDateFormatter alloc] init];
    [refDateFormatter setDateFormat:@"MM/dd/yy"];
    CPTTimeFormatter *timeFormatter =[[CPTTimeFormatter alloc] initWithDateFormatter:refDateFormatter];
    timeFormatter.referenceDate = refDate;
    x.labelFormatter = timeFormatter;
     
    //[graph reloadData];

     
    //animation
    dataTimer = [NSTimer timerWithTimeInterval:0.5/kFrameRate
                                        target:self
                                      selector:@selector(newData:)
                                      userInfo:nil
                                       repeats:YES];
	[[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];
    
    [rulerPlot reloadData];
    
};



-(void)prepareAnimationData{
    
    //set up unit of change for animation
    animationUnit = [NSMutableArray arrayWithCapacity:2000]; 
  
    for (int r=0;r<NoOfDataPointsInRange;r++){
        
        CEIData *startData;
        CEIData *endData;
        CEIData *startDataAll;
        CEIData *endDataAll;
        float newPercent, newPercentAll, newPercentPrior;
        float oldPercent, oldPercentAll, oldPercentPrior;
        float diffPercent, diffPercentAll, diffPercentPrior;
        float unitPercent, unitPercentAll, unitPercentPrior;
                     
        if (r < [animationStartDailyKeys count]){
            startData = [dailyCEI objectForKey:[animationStartDailyKeys objectAtIndex:r]];
            startDataAll = [allCollectorsCEI objectForKey:[animationStartDailyKeys objectAtIndex:r]];
            
            //NSLog(@"2r=%i,startData",r);
        }
        else{ 
            startData = nil;
            startDataAll = nil;
        }
        
        if (r < [dailyKeysInRange count]){
            endData = [dailyCEI objectForKey:[dailyKeysInRange objectAtIndex:r]];
            endDataAll = [allCollectorsCEI objectForKey:[dailyKeysInRange objectAtIndex:r]];
            //NSLog(@"3r=%i,endData",r);
        }
        else{
            endData = nil;
            endDataAll = nil;
        }

        
        
        NSMutableDictionary *unitDict = [[NSMutableDictionary alloc] init];
        if (endData){
            newPercent = [endData.ceiPercent floatValue];
            newPercentPrior = [endData.priorYearPercent floatValue];
            newPercentAll = [endDataAll.ceiPercent floatValue];
        } else{  
            newPercent = 0;
            newPercentPrior = 0;
            newPercentAll = 0;
        }
        if (startData){
            oldPercent = [startData.ceiPercent floatValue];
            oldPercentPrior = [startData.priorYearPercent floatValue];
            oldPercentAll = [startDataAll.ceiPercent floatValue];
        } else{  
            oldPercent = 0;
            oldPercentPrior = 0;
            oldPercentAll = 0;
        }
        
        //if ((newPercent != 0) && (oldPercent != 0))   
        if ((endData) && (startData))
            diffPercent = newPercent - oldPercent;
        else diffPercent = 0;
        //if ((newPercentPrior != 0) && (oldPercentPrior != 0))
        if ((endData) && (startData))
            diffPercentPrior = newPercentPrior - oldPercentPrior;
        else diffPercentPrior = 0;
        //if ((newPercentAll != 0) && (oldPercentAll != 0))
        if ((endData) && (startData))
            diffPercentAll = newPercentAll - oldPercentAll;
        else diffPercentAll = 0;
                   

        unitPercent = diffPercent / kRepeat;
        unitPercentPrior = diffPercentPrior / kRepeat;
        unitPercentAll = diffPercentAll / kRepeat;
        
        [unitDict setObject:[NSNumber numberWithFloat:unitPercent] forKey:@"current"];
        [unitDict setObject:[NSNumber numberWithFloat:unitPercentPrior] forKey:@"prior"];
        [unitDict setObject:[NSNumber numberWithFloat:unitPercentAll] forKey:@"all"];
      
        
        [animationUnit addObject:unitDict];
       
    }
    
}

-(void)newData:(NSTimer *)theTimer
{
    /*
    int animationPoints = [animationStartDailyKeys count] < NoOfDataPointsInRange ? [animationStartDailyKeys count] : NoOfDataPointsInRange;
    
    for (int i=0; i< animationPoints; i++){
        
        CEIData *startData;
        CEIData *endData;
        CEIData *startDataAll;
        CEIData *endDataAll;
        NSString *endKey;
        float oldPercent, oldPercentPrior, oldPercentAll; 
        float intrimPercent, intrimPercentPrior, intrimPercentAll;
        float unitPercent, unitPercentPrior, unitPercentAll;
               
              
        if (i < [animationStartDailyKeys count]){
            startData = [dailyCEI objectForKey:[animationStartDailyKeys objectAtIndex:i]];
            startDataAll = [allCollectorsCEI objectForKey:[animationStartDailyKeys objectAtIndex:i]];
        }
        else{ 
            startData = nil;
            startDataAll = nil;
        }
        
        if (i < [dailyKeysInRange count]){
            endKey = [dailyKeysInRange objectAtIndex:i];
            endData = [dailyCEI objectForKey:endKey];
            endDataAll = [allCollectorsCEI objectForKey:endKey];
        }
        else{
            endData = nil;
            endDataAll = nil;
        }
        
        if (startData){
            oldPercent = [startData.ceiPercent floatValue];
            oldPercentPrior = [startData.priorYearPercent floatValue];
            oldPercentAll = [startDataAll.ceiPercent floatValue];
        };
            
        
        if (i < [animationStartDailyKeys count]){
            unitPercent = [[[animationUnit objectAtIndex:i] objectForKey:@"current"] floatValue];
            unitPercentPrior=[[[animationUnit objectAtIndex:i] objectForKey:@"prior"] floatValue];
            unitPercentAll = [[[animationUnit objectAtIndex:i] objectForKey:@"all"] floatValue];

        }
        
        intrimPercent = oldPercent + unitPercent * (timerCount+1);
        intrimPercentPrior = oldPercentPrior + unitPercentPrior * (timerCount+1);
        intrimPercentAll = oldPercentAll + unitPercentAll * (timerCount+1);
        if (unitPercentPrior ==0) intrimPercentPrior =0;//when no prior year data
                      
        //????this is not entirely correct as I need to change the bucket amounts instead
        if (endData){
            if (intrimPercent != 0.0){
                endData.ceiPercent = [NSNumber numberWithFloat:intrimPercent];
                endData.priorYearPercent = [NSNumber numberWithFloat:intrimPercentPrior];
                endDataAll.ceiPercent = [NSNumber numberWithFloat:intrimPercentAll];
                
                [dailyCEI removeObjectForKey:endKey];
                [dailyCEI setObject:endData forKey:endKey];
                [allCollectorsCEI removeObjectForKey:endKey];
                [allCollectorsCEI setObject:endDataAll forKey:endKey];
            }
        }
                
    }
    */
  
     
    
    [currentPlot reloadDataInIndexRange:NSMakeRange(0,NoOfDataPointsInRange)];
    [priorPlot reloadDataInIndexRange:NSMakeRange(0,NoOfDataPointsInRange)];
    [allCollectorsPlot reloadDataInIndexRange:NSMakeRange(0,NoOfDataPointsInRange)];
     
    
    timerCount++;
    if (timerCount >= kRepeat) {
        [theTimer invalidate];
        timerCount = 0;
    }
    
}



#pragma mark - CPTPlotSpace Delegate Methods
// This implementation of this method will put the line graph in a fix position so it won't be scrollable.

-(CPTPlotRange *)plotSpace:(CPTPlotSpace *)space willChangePlotRangeTo:(CPTPlotRange *)newRange forCoordinate:(CPTCoordinate)coordinate 
{
    
    if (coordinate == CPTCoordinateY) {
        return ((CPTXYPlotSpace *)space).yRange;
    }
    else
    {   
        //return newRange; //allow horizontal scrolling
        return ((CPTXYPlotSpace *)space).xRange;  //disable horizontal scrolling
    }
}



// This method is call when user touch & drag the ruler plot
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDraggedEvent:(id)event atPoint:(CGPoint)point
{
    
    if (!rulerEnabled){
        [self applyRulerPlotColor];
        [self displayRulerAnnotation]; 
        rulerEnabled = YES;
        [graph addPlot:rulerPlot];
        [rulerPlot reloadData];
    }

    
    // Convert the touch point to plot area frame location
    CGPoint pointInPlotArea = [graph convertPoint:point toLayer:graph.plotAreaFrame];
    NSDecimal newPoint[2];
    [graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
    NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
    
    int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
    
    
    if (!rulerEnabled){
        [self applyRulerPlotColor];
        [self displayRulerAnnotation]; 
        rulerEnabled = YES;
        [graph addPlot:rulerPlot];
        [rulerPlot reloadData];
    }
    
    //int maxRange = initNumberOfDaysDisplayed;
    int maxRange = NoOfDataPointsInRange;
    
    /*if ((rangeChanged) && (NoOfDataPointsInRange > initNumberOfDaysDisplayed)) 
        maxRange = NoOfDataPointsInRange; */
    
    int totalRange = oneDayInterval*maxRange; 
    if (x > totalRange)
    {
        if (rulerIndex <= (NoOfDataPointsInRange-2)){
            rulerIndex = rulerIndex + 1;
        }
    } else if (x < 0){
        if (rulerIndex >=1){
            rulerIndex = rulerIndex - 1;
        }
    }
    
    else {
        //int totalRange = oneDayInterval*maxRange;
        //x =  x/(totalRange/NoOfDataPointsInRange);
         x =  x/oneDayInterval;       
        if (x < NoOfDataPointsInRange)
            rulerIndex = x;
    };
    

    selectedDateString = [dailyKeysInRange objectAtIndex:rulerIndex];
    rulerDateString = selectedDateString;
    //[self highlightRulerPlotColor];
    [self displayRulerAnnotation];
    [rulerPlot reloadData];

    return YES;
       
    /*int maxRange = initNumberOfDaysDisplayed;
   
    if ((rangeChanged) && (NoOfDataPointsInRange > initNumberOfDaysDisplayed)) 
        maxRange = NoOfDataPointsInRange; 
    
    int totalRange = oneDayInterval*maxRange; 
    
    if ((x > totalRange) || ( x < 0))
    {
        return NO;
    }
    else {
        int totalRange = oneDayInterval*maxRange;
        x =  x/(totalRange/NoOfDataPointsInRange);
        if (x < [dailyKeysInRange count]){
           
            selectedDateString = [dailyKeysInRange objectAtIndex:x];
            rulerDateString = selectedDateString;
            rulerIndex = x;
            //[self highlightRulerPlotColor];
            [self displayRulerAnnotation];
            [rulerPlot reloadData];
        }
        
        return YES;
    };
   
    return YES;*/
    
    
}



- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDownEvent:(id)event 
          atPoint:(CGPoint)point
{
    // Convert the touch point to plot area frame location
    CGPoint pointInPlotArea = [graph convertPoint:point toLayer:graph.plotAreaFrame];
    NSDecimal newPoint[2];
    [graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
    NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
    
    int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
    
    //int maxRange = initNumberOfDaysDisplayed;
    //if ((rangeChanged) && (numberOfDaysInRange > initNumberOfDaysDisplayed)) 
    //    maxRange = numberOfDaysInRange; 
    //int totalRange = oneDayInterval*numberOfDaysInRange; 
    x =  x/oneDayInterval;
    
    if (rulerEnabled){
        [graph removePlot:rulerPlot];
        [self removeRulerAnnotation];
        rulerEnabled = NO;
    } else{
        rulerIndex = x;
        rulerDateString = [dailyKeysInRange objectAtIndex:x];
        [self applyRulerPlotColor];
        [self displayRulerAnnotation]; 
        rulerEnabled = YES;
        [graph addPlot:rulerPlot];
        [rulerPlot reloadData];
        
        
    }
    
    
    return YES;
}

- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceUpEvent:(id)event atPoint:(CGPoint)point
{
   
    // Convert the touch point to plot area frame location
    CGPoint pointInPlotArea = [graph convertPoint:point toLayer:graph.plotAreaFrame];
    NSDecimal newPoint[2];
    [graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
    NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
    
    int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
    int maxRange = initNumberOfDaysDisplayed;
    
    if ((rangeChanged) && (NoOfDataPointsInRange > initNumberOfDaysDisplayed)) 
        maxRange = NoOfDataPointsInRange; 

    int totalRange = oneDayInterval*maxRange; 
    
    if ((x > totalRange) || ( x < 0)){
        return NO;
    }
    else {
        
        int totalRange = oneDayInterval*maxRange;
        x =  x/(totalRange/NoOfDataPointsInRange);
        
        selectedDateString = [dailyKeysInRange objectAtIndex:x];
               
        rulerDateString = selectedDateString;
        rulerIndex = x;
        [self applyRulerPlotColor];
        return YES;
    };
    
}


#pragma mark - 
#pragma mark Scatter plot delegate methods
/*
- (void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index
{
    
    if ([(NSString *)plot.identifier isEqualToString:kRulerPlot]) 
    {
        //rulerPlotSelected = YES;
        //[self applyHighLightPlotColor:plot];
        //if ([delegate respondsToSelector:@selector(linePlot:selectedDate:)]) 
        //    [delegate linePlot:self selectedDate:selectedDateString];
        
    } 
    
}
*/


#pragma mark -
#pragma mark Plot Data Source Methods

- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
    
    if ([(NSString *)plot.identifier isEqualToString:kRulerPlot])
        return numberOfMarkerPlotSymbols;
    
    else 
        return NoOfDataPointsInRange;
}

- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{       
    NSNumber *num = nil;
    
        
    
    
    if ([(NSString *)plot.identifier isEqualToString:kCurrentPlot]){
        
        CEIData *startData, *endData, *indexData;
        
        NSString *refDateString = [dailyKeysInRange objectAtIndex:0];
        CEIData *refData = [dailyCEI objectForKey:refDateString];
        NSString *indexDateString = [dailyKeysInRange objectAtIndex:index];
        endData = [dailyCEI objectForKey:indexDateString];
        
        if (index < [animationStartDailyKeys count]){
            NSString *startDateString = [animationStartDailyKeys objectAtIndex:index];
            startData = [dailyCEI objectForKey: startDateString];
        } else startData = nil;
        
        if (startData)
            indexData = startData;
        else indexData = endData;
        
        NSDictionary *unitDict = [animationUnit objectAtIndex:index];
        NSNumber *unitPercent = [unitDict objectForKey:@"current"];
     
                
        if ( fieldEnum == CPTScatterPlotFieldY ){
            
            float percent = [indexData.ceiPercent floatValue];
            float currentPercent = 
            percent + [unitPercent floatValue] * (timerCount+1);
            num = [NSNumber numberWithFloat:currentPercent];
            
                       
            //num= indexData.ceiPercent;
        } else if (fieldEnum == CPTScatterPlotFieldX){
            num=[NSNumber numberWithFloat: (refData.timeIntervalSinceToday - endData.timeIntervalSinceToday)];
        }
    }
    
    if ([(NSString *)plot.identifier isEqualToString:kPriorPlot]){
        
        /*NSString *refDateString = [dailyKeysInRange objectAtIndex:0];
        CEIData *refData = [dailyCEI objectForKey:refDateString];
        NSString *indexDateString = [dailyKeysInRange objectAtIndex:index];
        CEIData *indexData = [dailyCEI objectForKey:indexDateString];*/
                
        CEIData *startData, *endData, *indexData;
        
        NSString *refDateString = [dailyKeysInRange objectAtIndex:0];
        CEIData *refData = [dailyCEI objectForKey:refDateString];
        NSString *indexDateString = [dailyKeysInRange objectAtIndex:index];
        endData = [dailyCEI objectForKey:indexDateString];
        
        if (index < [animationStartDailyKeys count]){
            NSString *startDateString = [animationStartDailyKeys objectAtIndex:index];
            startData = [dailyCEI objectForKey: startDateString];
        } else startData = nil;
        
        if (startData)
            indexData = startData;
        else indexData = endData;
        
        NSDictionary *unitDict = [animationUnit objectAtIndex:index];
        NSNumber *unitPercentPrior = [unitDict objectForKey:@"prior"];
      
        
        if ( fieldEnum == CPTScatterPlotFieldY ){
            float percent = [indexData.priorYearPercent floatValue];
            float priorPercent = 
            percent + [unitPercentPrior floatValue] * (timerCount+1);
            num = [NSNumber numberWithFloat:priorPercent];
            
            //num= indexData.priorYearPercent;
        } else if (fieldEnum == CPTScatterPlotFieldX){
            num=[NSNumber numberWithFloat: (refData.timeIntervalSinceToday - endData.timeIntervalSinceToday)];
        }
    }

    
    if ([(NSString *)plot.identifier isEqualToString:kAllCollectorsPlot]){
        
        /*NSString *refDateString = [allCollectorsKeysInRange objectAtIndex:0];
        CEIData *refData = [allCollectorsCEI objectForKey:refDateString];
        NSString *indexDateString = [allCollectorsKeysInRange objectAtIndex:index];
        CEIData *indexData = [allCollectorsCEI objectForKey:indexDateString];*/
        
        CEIData *startData, *endData, *indexData;
        
        NSString *refDateString = [allCollectorsKeysInRange objectAtIndex:0];
        CEIData *refData = [allCollectorsCEI objectForKey:refDateString];
        NSString *indexDateString = [allCollectorsKeysInRange objectAtIndex:index];
        endData = [allCollectorsCEI objectForKey:indexDateString];
        
        if (index < [animationStartDailyKeys count]){
            NSString *startDateString = [animationStartDailyKeys objectAtIndex:index];
            startData = [allCollectorsCEI objectForKey: startDateString];
        } else startData = nil;
        
        if (startData)
            indexData = startData;
        else indexData = endData;
        
        NSDictionary *unitDict = [animationUnit objectAtIndex:index];
        NSNumber *unitPercentAll = [unitDict objectForKey:@"all"];

        
        if ( fieldEnum == CPTScatterPlotFieldY ){
            float percent = [indexData.ceiPercent floatValue];
            float allPercent = 
            percent + [unitPercentAll floatValue] * (timerCount+1);
            num = [NSNumber numberWithFloat:allPercent];
            
            /*if (index ==(50 ))
                //if (index ==(NoOfDataPointsInRange-1))
                NSLog(@"index=%i,timerCount=%i,origPer=%f,unit=%f,newPer=%f, endPer=%f",index,timerCount,percent,[unitPercentAll floatValue],allPercent,[endData.ceiPercent floatValue]);
            */


            //num= indexData.ceiPercent;
        } else if (fieldEnum == CPTScatterPlotFieldX){
            num=[NSNumber numberWithFloat: (refData.timeIntervalSinceToday - endData.timeIntervalSinceToday)];
        }
    }

    if ([(NSString *)plot.identifier isEqualToString:kRulerPlot]){
        
        if ( fieldEnum == CPTScatterPlotFieldY ) 
        {
            switch (index) {
                case 0:
                    num = [NSNumber numberWithInt:0];
                    break; 
                case 1:
                    num = [NSNumber numberWithInt:100];
                    break;    
                default:
                    num = [NSNumber numberWithInt:0];
                    break;
            }
        } 
        else if (fieldEnum == CPTScatterPlotFieldX) 
        {   
           
            NSString *refDateString = [dailyKeysInRange objectAtIndex:0];
            CEIData *refData = [dailyCEI objectForKey:refDateString];
            CEIData *rulerData = [dailyCEI objectForKey:rulerDateString];
                  
            num=[NSNumber numberWithFloat: (refData.timeIntervalSinceToday - rulerData.timeIntervalSinceToday)];
        }
    }

    
        
    return num;
}




@end
